package lumis.util.converter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

/**
 * Perform conversions from or to collection types.
 * 
 * @since 4.0.6
 * @version $Revision: 11576 $ $Date: 2010-05-18 16:14:52 -0300 (Tue, 18 May 2010) $
 */
public class CollectionConverter extends AbstractConverter
{
	@SuppressWarnings("unchecked")
	@Override
	protected <T> T doConversion(Class<T> type, Object value, Locale locale,
			String pattern) throws UnsupportedConversionTypeException
	{
		if (type.isAssignableFrom(List.class))
		{
			if (value instanceof Object[])
			{
				ArrayList a = new ArrayList();
				for (Object o : (Object[]) value)
				{
					a.add(o);
				}				
				return (T) a;
			}
			else if (value instanceof Iterable)
			{
				ArrayList a = new ArrayList();
				for (Object o : (Iterable) value)
				{
					a.add(o);
				}
				return (T) a;
			}
			else 
			{
				// if the value is not iterable, create an ArrayList of only one item
				ArrayList a = new ArrayList();
				a.add(value);
				return (T) a;
			}
		}
		else
		{
			if (value instanceof Object[])
			{
				Object[] array = (Object[]) value;
				if (array.length == 0)
				{
					return null;
				}
				else if (array.length == 1)
				{
					if (type.isAssignableFrom(array[0].getClass()))
					{
						return (T) array[0];
					}
					else
					{
						return ConvertUtil.convert(type, array[0], locale, pattern);
					}
				}
				else
				{
					throw new UnsupportedConversionTypeException(value.getClass().getName());
				}
			}
			// if value is an iterable of only one item, and this item is
			// compatible with type, convert the item to the type
			else if (value instanceof Iterable)
			{	
				Iterator i = ((Iterable) value).iterator();
				
				if (i.hasNext())
				{
					Object o = i.next();
					if (!i.hasNext())
					{
						if (type.isAssignableFrom(o.getClass()))
						{
							return (T) o;
						}
						else
						{
							return ConvertUtil.convert(type, o, locale, pattern);
						}
					}
				}
				else
				{
					return null;
				}
			}
			throw new UnsupportedConversionTypeException(value.getClass().getName());
		}
	}
}